﻿using Cms.Domain;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Cms.Tests.Unit.Domain
{
    [TestClass]
    public class SiteTests
    {
        [TestMethod]
        public void TestGetLocaleByUrlCode()
        {
            Site site = new Site();
            Assert.IsNull(site.GetLocaleByUrlCode("en"));
            Locale locale = new Locale
                                {
                                    UrlCode = "en"
                                };
            site.Locales.Add(locale);
            Assert.AreSame(locale, site.GetLocaleByUrlCode("en"));
            locale = new Locale
            {
                UrlCode = "se"
            };
            site.Locales.Add(locale);
            Assert.AreSame(locale, site.GetLocaleByUrlCode("se"));
            Assert.IsNull(site.GetLocaleByUrlCode("fi"));
        }

        [TestMethod]
        public void TestGetRootFolders()
        {
            Site site = new Site();
            Folder a = new Folder {Site = site};
            Folder b = new Folder { Site = site };
            Folder c = new Folder { Site = site };
            Folder d = new Folder { Site = site };
            site.Folders.Add(a);
            site.Folders.Add(b);
            site.Folders.Add(c);
            site.Folders.Add(d);
            a.SubFolders.Add(b);
            b.Parent = a;
            c.SubFolders.Add(d);
            d.Parent = c;
            Assert.AreEqual(2, site.GetRootFolders().Count);
        }
        
        [TestMethod]
        public void TestGetRootPages()
        {
            Site site = new Site();
            Folder folder = new Folder { Site = site };
            Page pageA = new Page { Site = site };
            Page pageB = new Page { Site = site };
            Page pageC = new Page { Site = site };
            site.Folders.Add(folder);
            site.Pages.Add(pageA);
            site.Pages.Add(pageB);
            site.Pages.Add(pageC);
            folder.Pages.Add(pageB);
            pageB.Folder = folder;
            Assert.AreEqual(2, site.GetRootPages().Count);
        }

        [TestMethod]
        public void CanFolderBeNamedAndMovedTo_NoNamingConflict_Success()
        {
            Site site = new Site();
            Folder folderA = new Folder { Site = site, ID = 1, Name = "A" };
            site.Folders.Add(folderA);
            Folder folderB = new Folder { Site = site, ID = 1, Name = "B" };
            site.Folders.Add(folderB);
            Assert.IsTrue(site.CanFolderBeNamedAndMovedTo(1, "A", folderB));
        }
        
        [TestMethod]
        public void CanFolderBeNamedAndMovedTo_NamingConflict_Failure()
        {
            Site site = new Site();
            Folder folderA = new Folder { Site = site, ID = 1, Name = "A" };
            site.Folders.Add(folderA);
            Folder folderB = new Folder { Site = site, ID = 2, Name = "B" };
            site.Folders.Add(folderB);
            Assert.IsFalse(site.CanFolderBeNamedAndMovedTo(2, "A", null));
        }
        
        [TestMethod]
        public void CanPageBeNamedAndMovedTo_NoNamingConflict_Success()
        {
            Site site = new Site();
            Page pageA = new Page { Site = site, ID = 1, Filename = "A" };
            site.Pages.Add(pageA);
            Folder folderA = new Folder() { Site = site, ID = 1, Name = "FolderA" };
            site.Folders.Add(folderA);
            Assert.IsTrue(site.CanPageBeNamedAndMovedTo(1, "A", folderA));
        }

        [TestMethod]
        public void CanPageBeNamedAndMovedTo_NamingConflict_Failure()
        {
            Site site = new Site();
            Page pageA = new Page { Site = site, ID = 1, Filename = "A" };
            site.Pages.Add(pageA);
            Folder folderA = new Folder() { Site = site, ID = 1, Name = "FolderA" };
            site.Folders.Add(folderA);
            Page pageB = new Page { Site = site, ID = 2, Filename = "B", Folder = folderA };
            site.Pages.Add(pageA);
            folderA.Pages.Add(pageB);
            Assert.IsFalse(site.CanPageBeNamedAndMovedTo(2, "A", null));
        }
        
        private Site SetupCanMasterTemplateBeNamedToTests()
        {
            Site site = new Site();
            MasterTemplate mtA = new MasterTemplate() { Site = site, ID = 1, Name = "A" };
            MasterTemplate mtB = new MasterTemplate() { Site = site, ID = 2, Name = "B" };
            site.MasterTemplates.Add(mtA);
            site.MasterTemplates.Add(mtB);
            return site;
        }
        
        [TestMethod]
        public void CanMasterTemplateBeNamedTo_NoNamingConflict_Success()
        {
            Site site = SetupCanMasterTemplateBeNamedToTests();
            Assert.IsTrue(site.CanMasterTemplateBeNamedTo(1, "C"));
        }

        [TestMethod]
        public void CanMasterTemplateBeNamedTo_NamingConflict_Failure()
        {
            Site site = SetupCanMasterTemplateBeNamedToTests();
            Assert.IsFalse(site.CanMasterTemplateBeNamedTo(1, "B"));
        }
        
        private Site SetupCanDetailTemplateBeNamedToTests()
        {
            Site site = new Site();
            DetailTemplate dtA = new DetailTemplate() { Site = site, ID = 1, Name = "A" };
            DetailTemplate dtB = new DetailTemplate() { Site = site, ID = 2, Name = "B" };
            site.DetailTemplates.Add(dtA);
            site.DetailTemplates.Add(dtB);
            return site;
        }
        
        [TestMethod]
        public void CanDetailTemplateBeNamedTo_NoNamingConflict_Success()
        {
            Site site = SetupCanDetailTemplateBeNamedToTests();
            Assert.IsTrue(site.CanDetailTemplateBeNamedTo(1, "C"));
        }

        [TestMethod]
        public void CanDetailTemplateBeNamedTo_NamingConflict_Failure()
        {
            Site site = SetupCanDetailTemplateBeNamedToTests();
            Assert.IsFalse(site.CanDetailTemplateBeNamedTo(1, "B"));
        }
        
        private Site SetupCanStylesheetBeNamedToTests()
        {
            Site site = new Site();
            Stylesheet a = new Stylesheet() { Site = site, ID = 1, Name = "A" };
            Stylesheet b = new Stylesheet() { Site = site, ID = 2, Name = "B" };
            site.Stylesheets.Add(a);
            site.Stylesheets.Add(b);
            return site;
        }
        
        [TestMethod]
        public void CanStylesheetBeNamedTo_NoNamingConflict_Success()
        {
            Site site = SetupCanStylesheetBeNamedToTests();
            Assert.IsTrue(site.CanStylesheetBeNamedTo(1, "C"));
        }

        [TestMethod]
        public void CanStylesheetBeNamedTo_NamingConflict_Failure()
        {
            Site site = SetupCanStylesheetBeNamedToTests();
            Assert.IsFalse(site.CanStylesheetBeNamedTo(1, "B"));
        }
        
        private Site SetupCanLocaleHaveUrlCodeTests()
        {
            Site site = new Site();
            Locale en = new Locale() { Site = site, ID = 1, UrlCode = "en" };
            Locale se = new Locale() { Site = site, ID = 2, UrlCode = "se" };
            site.Locales.Add(en);
            site.Locales.Add(se);
            return site;
        }

        [TestMethod]
        public void CanLocaleHaveUrlCode_NoNamingConflict_Success()
        {
            Site site = SetupCanLocaleHaveUrlCodeTests();
            Assert.IsTrue(site.CanLocaleHaveUrlCode(1, "fi"));
        }

        [TestMethod]
        public void CanLocaleHaveUrlCode_NamingConflict_Failure()
        {
            Site site = SetupCanLocaleHaveUrlCodeTests();
            Assert.IsFalse(site.CanLocaleHaveUrlCode(1, "se"));
        }
        
        [TestMethod]
        public void TestGetRootMediaFolders()
        {
            Site site = new Site();
            MediaFolder a = new MediaFolder { Site = site };
            MediaFolder b = new MediaFolder { Site = site };
            MediaFolder c = new MediaFolder { Site = site };
            MediaFolder d = new MediaFolder { Site = site };
            site.MediaFolders.Add(a);
            site.MediaFolders.Add(b);
            site.MediaFolders.Add(c);
            site.MediaFolders.Add(d);
            a.SubFolders.Add(b);
            b.Parent = a;
            c.SubFolders.Add(d);
            d.Parent = c;
            Assert.AreEqual(2, site.GetRootMediaFolders().Count);
        }
        
        [TestMethod]
        public void TestGetRootMediaFiles()
        {
            Site site = new Site();
            MediaFolder folder = new MediaFolder { Site = site };
            MediaFile fileA = new MediaFile { Site = site };
            MediaFile fileB = new MediaFile { Site = site };
            MediaFile fileC = new MediaFile { Site = site };
            site.MediaFolders.Add(folder);
            site.MediaFiles.Add(fileA);
            site.MediaFiles.Add(fileB);
            site.MediaFiles.Add(fileC);
            folder.Files.Add(fileB);
            fileB.Folder = folder;
            Assert.AreEqual(2, site.GetRootMediaFiles().Count);
        }
        
        [TestMethod]
        public void CanMediaFolderBeNamedAndMovedTo_NoNamingConflict_Success()
        {
            Site site = new Site();
            MediaFolder folderA = new MediaFolder { Site = site, ID = 1, Name = "A" };
            site.MediaFolders.Add(folderA);
            MediaFolder folderB = new MediaFolder { Site = site, ID = 1, Name = "B" };
            site.MediaFolders.Add(folderB);
            Assert.IsTrue(site.CanMediaFolderBeNamedAndMovedTo(1, "A", folderB));
        }
        
        [TestMethod]
        public void CanMediaFolderBeNamedAndMovedTo_NamingConflict_Failure()
        {
            Site site = new Site();
            MediaFolder folderA = new MediaFolder { Site = site, ID = 1, Name = "A" };
            site.MediaFolders.Add(folderA);
            MediaFolder folderB = new MediaFolder { Site = site, ID = 2, Name = "B" };
            site.MediaFolders.Add(folderB);
            Assert.IsFalse(site.CanMediaFolderBeNamedAndMovedTo(2, "A", null));
        }
        
        [TestMethod]
        public void CanMediaFileBeNamedAndMovedTo_NoNamingConflict_Success()
        {
            Site site = new Site();
            MediaFile fileA = new MediaFile { Site = site, ID = 1, Name = "A" };
            site.MediaFiles.Add(fileA);
            MediaFolder folderA = new MediaFolder() { Site = site, ID = 1, Name = "FolderA" };
            site.MediaFolders.Add(folderA);
            Assert.IsTrue(site.CanMediaFileBeNamedAndMovedTo(1, "A", folderA));
        }

        [TestMethod]
        public void CanMediaFileBeNamedAndMovedTo_NamingConflict_Failure()
        {
            Site site = new Site();
            MediaFile fileA = new MediaFile { Site = site, ID = 1, Name = "A" };
            site.MediaFiles.Add(fileA);
            MediaFolder folderA = new MediaFolder() { Site = site, ID = 1, Name = "FolderA" };
            site.MediaFolders.Add(folderA);
            MediaFile fileB = new MediaFile { Site = site, ID = 2, Name = "B", Folder = folderA };
            site.MediaFiles.Add(fileA);
            folderA.Files.Add(fileB);
            Assert.IsFalse(site.CanMediaFileBeNamedAndMovedTo(2, "A", null));
        }
        
        [TestMethod]
        public void GetMediaFolder_ByPath()
        {
            Site site = new Site() { RootMediaFolder = "media" };
            MediaFolder folderA = new MediaFolder { Site = site, Name = "folderA" };
            MediaFolder folderB = new MediaFolder { Site = site, Name = "folderB", Parent = folderA };
            site.MediaFolders.Add(folderA);
            site.MediaFolders.Add(folderB);
            folderA.SubFolders.Add(folderB);
            Assert.AreSame(folderB, site.GetMediaFolder("folderA/folderB"));
            Assert.IsNull(site.GetMediaFolder("folderB/folderA"));
        }
        
        [TestMethod]
        public void GetMediaFile_ByPath()
        {
            Site site = new Site() { RootMediaFolder = "media" };
            MediaFolder folder = new MediaFolder { Site = site, Name = "folder" };
            site.MediaFolders.Add(folder);
            MediaFile a = new MediaFile { Site = site, Name = "a", Folder = null };
            site.MediaFiles.Add(a);
            Assert.AreSame(a, site.GetRootMediaFile("a"));
            MediaFile b = new MediaFile { Site = site, Name = "b", Folder = folder };
            folder.Files.Add(b);
            site.MediaFiles.Add(b);
            Assert.AreSame(b, site.GetMediaFile("folder", "b"));
        }

        [TestMethod]
        public void GetState_NewSite_Success()
        {
            Site site = new Site();
            Assert.AreEqual("Domain = , AliasDomains = , MasterTemplate = ", site.GetState());
        }

        [TestMethod]
        public void GetState_EditSite_Success()
        {
            Site site = new Site();
            site.Domain = "fredium.dev";
            site.AliasDomains.Add("demo.fredium.dev");
            site.AliasDomains.Add("test.fredium.dev");
            Assert.AreEqual("Domain = fredium.dev, AliasDomains = demo.fredium.dev, test.fredium.dev, MasterTemplate = ", site.GetState());
        }
    }
}
